package cn.gary.oaserver.service.impl;

import cn.gary.oaserver.config.utils.PageUtil;
import cn.gary.oaserver.entity.TAdminRole;
import cn.gary.oaserver.entity.TMenu;
import cn.gary.oaserver.entity.TMenuRole;
import cn.gary.oaserver.entity.TRole;
import cn.gary.oaserver.entity.vo.AdminRoleVO;
import cn.gary.oaserver.entity.vo.RoleVo;
import cn.gary.oaserver.mapper.TRoleMapper;
import cn.gary.oaserver.params.PageParams;
import cn.gary.oaserver.service.ITMenuRoleService;
import cn.gary.oaserver.service.ITMenuService;
import cn.gary.oaserver.service.ITRoleService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author gary
 * @since 2024-03-15
 */
@Service
public class TRoleServiceImpl extends ServiceImpl<TRoleMapper, TRole> implements ITRoleService {

    @Autowired
    ITMenuService menuService;

    @Autowired
    ITMenuRoleService menuRoleService;

    @Override
    public AdminRoleVO getListByAdminId(Integer adminId) {
        List<TAdminRole> roles = baseMapper.getListByAdminId ( adminId );
        List<Integer> ids = new ArrayList<> ( );
        for (TAdminRole adminRole : roles) {
            ids.add ( adminRole.getRid ( ) );
        }
        return new AdminRoleVO ( adminId, ids.toArray ( new Integer[ids.size ( )] ) );
    }

    @Override
    public PageUtil<RoleVo> getRoleAndMenuTree(PageParams pageParams, String queryStr) {
        Page<TRole> page = new Page<> ( pageParams.getPageIndex ( ), pageParams.getPageSize ( ) );
        QueryWrapper<TRole> qw = new QueryWrapper<> ( );
        if (queryStr != null) {
            qw.like ( "name", queryStr ).or ( ).like ( "nameZh", queryStr );
            if (pageParams.getSort ( ).startsWith ( "asc" ) && pageParams.getSort ( ).contains ( "_" )) {
                qw.orderByAsc ( pageParams.getSort ( ).substring ( pageParams.getSort ( ).indexOf ( "_" ) + 1 ) );
            } else {
                qw.orderByDesc ( pageParams.getSort ( ).substring ( pageParams.getSort ( ).indexOf ( "_" ) + 1 ) );
            }
        }
        IPage<TRole> rolePage = baseMapper.selectPage ( page, qw );
        List<RoleVo> roleVoList = getRoleMenuChildren ( rolePage.getRecords ( ) );
        int pageIndex = (int) rolePage.getCurrent ( );
        int total = (int) rolePage.getTotal ( );
        PageUtil<RoleVo> pageUtil = new PageUtil<> ( pageIndex, total, roleVoList );
        return pageUtil;
    }

    @Override
    @Transactional
    public boolean removeRoleAndMenuRoleById(Integer id) {
        QueryWrapper<TMenuRole> qw = new QueryWrapper<> ( );
        qw.eq ( "rid", id );
        menuRoleService.remove ( qw );
        int flag = baseMapper.deleteById ( id );
        return flag > 0;
    }

    private List<RoleVo> getRoleMenuChildren(List<TRole> roles) {
        List<RoleVo> roleVoList = new ArrayList<RoleVo> ( );
        for (TRole role : roles) {
            RoleVo roleVo = new RoleVo ( );
            roleVo.setRole ( role );
            List<TMenu> menuList = new ArrayList<TMenu> ( );
            List<TMenu> menusByRoleId = menuService.getMenusByRoleId ( role.getId ( ) );
            for (TMenu tMenu : menusByRoleId) {
                if (tMenu.getMenuLevel ( ) != null && tMenu.getMenuLevel ( ) == 1) {
                    tMenu.setChildren ( getMenuVOList ( tMenu.getId ( ), menusByRoleId, role ) );
                    menuList.add ( tMenu );
                }
            }
            roleVo.setChildren ( menuList );
            roleVoList.add ( roleVo );
        }
        return roleVoList;
    }

    private List<TMenu> getMenuVOList(Integer id, List<TMenu> list, TRole role) {
        ArrayList<TMenu> tMenus = new ArrayList<> ( );
        for (TMenu tMenu : list) {
            if (tMenu.getParentId ( ).equals ( id )) {
                tMenu.setChildren ( getMenuVOList ( tMenu.getId ( ), list, role ) );
                tMenus.add ( tMenu );
            }
        }
        return tMenus;
    }
}
